﻿using System;
using System.Runtime;
using System.Text;
using System.Web;
namespace System.Web.Hosting
{
    internal class RecyclableByteBuffer
    {
        private byte[] _byteBuffer = ((byte[])_byteBufferAllocator.GetBuffer());
        private char[] _charBuffer;
        private int _offset;
        private bool _recyclable = true;
        private const int BUFFER_SIZE = 0x1000;
        private const int MAX_FREE_BUFFERS = 0x40;
        private static UbyteBufferAllocator _byteBufferAllocator = new UbyteBufferAllocator(0x1000, 0x40);
        private static CharBufferAllocator _charBufferAllocator = new CharBufferAllocator(0x1000, 0x40);

        private int CalcLength()
        {
            if (_byteBuffer != null)
            {
                int length = _byteBuffer.Length;
                for (int index = _offset; index < length; index++)
                    if (_byteBuffer[index] == 0)
                        return (index - _offset);
            }
            return 0;
        }

        internal void Dispose()
        {
            if (_recyclable)
            {
                if (_byteBuffer != null)
                    _byteBufferAllocator.ReuseBuffer(_byteBuffer);
                if (_charBuffer != null)
                    _charBufferAllocator.ReuseBuffer(_charBuffer);
            }
            _byteBuffer = null;
            _charBuffer = null;
        }

        private char[] GetDecodedCharBuffer(Encoding encoding, ref int len)
        {
            if (_charBuffer == null)
                if (len == 0)
                    _charBuffer = new char[0];
                else if (_recyclable)
                {
                    _charBuffer = (char[])_charBufferAllocator.GetBuffer();
                    len = encoding.GetChars(_byteBuffer, _offset, len, _charBuffer, 0);
                }
                else
                {
                    _charBuffer = encoding.GetChars(_byteBuffer, _offset, len);
                    len = _charBuffer.Length;
                }
            return _charBuffer;
        }

        internal string GetDecodedString(Encoding encoding, int len)
        {
            return encoding.GetString(_byteBuffer, 0, len);
        }

        internal string[] GetDecodedTabSeparatedStrings(Encoding encoding, int numStrings, int numSkipStrings)
        {
            int num3;
            if (numSkipStrings > 0)
                Skip(numSkipStrings);
            int len = CalcLength();
            var decodedCharBuffer = GetDecodedCharBuffer(encoding, ref len);
            var strArray = new string[numStrings];
            int startIndex = 0;
            int num4 = 0;
            for (int i = 0; i < numStrings; i++)
            {
                num3 = len;
                for (int j = startIndex; j < len; j++)
                    if (decodedCharBuffer[j] == '\t')
                    {
                        num3 = j;
                        break;
                    }
                strArray[i] = (num3 > startIndex ? new string(decodedCharBuffer, startIndex, num3 - startIndex) : string.Empty);
                num4++;
                if (num3 == len)
                    break;
                startIndex = num3 + 1;
            }
            if (num4 < numStrings)
            {
                len = CalcLength();
                startIndex = _offset;
                for (int k = 0; k < numStrings; k++)
                {
                    num3 = len;
                    for (int m = startIndex; m < len; m++)
                        if (_byteBuffer[m] == 9)
                        {
                            num3 = m;
                            break;
                        }
                    strArray[k] = (num3 > startIndex ? encoding.GetString(_byteBuffer, startIndex, num3 - startIndex) : string.Empty);
                    if (num3 == len)
                        return strArray;
                    startIndex = num3 + 1;
                }
            }
            return strArray;
        }

        internal void Resize(int newSize)
        {
            _byteBuffer = new byte[newSize];
            _recyclable = false;
        }

        private void Skip(int count)
        {
            if (count > 0)
            {
                int length = _byteBuffer.Length;
                int num2 = 0;
                for (int index = 0; index < length; index++)
                    if ((_byteBuffer[index] == 9) && (++num2 == count))
                    {
                        _offset = index + 1;
                        return;
                    }
            }
        }

        internal byte[] Buffer
        {
            get { return _byteBuffer; }
        }
    }
}
